/**
 * form - jQuery xui
 *
 * Licensed under the GPL:
 *   http://www.gnu.org/licenses/gpl.txt
 *
 * Copyright 2015 xjb [ beymy.en@gmail.com ]
 *
 * 依赖
 *   mask
 */
(function($) {
    /**
     * ajax提交表单
     */
    function ajaxSubmit(target, options) {
        options = options || {};

        if (options.onSubmit) {
            if (options.onSubmit.call(target) == false) {
                return;
            }
        }

        var form = $(target);
        if (!options.url) {
            options.url = form.attr('action');
        }

        form.mask().mask('show');
        $.ajax({
            type: 'POST',
            url: options.url,
            contentType: 'application/json',
            dataType: 'json',
            data: $.toJSON(form.serialize()),
            success: function(data) {
                form.mask('hide');
                options.success.call(target, data);
            },
            error: function() {
                form.mask('hide');
            }
        });
    }

    /**
     * 加载表单数据
     * 如果data是string类型则代表URL,从远程加载数据
     * 否则加载本地object
     */
    function load(target, data) {
        if (typeof data == 'string') {
            $.ajax({
                url: data,
                dataType: 'json',
                success: function(data) {
                    _load(data);
                }
            });
        } else {
            _load(data);
        }

        function _load(data) {
            var form = $(target);
            for (var name in data) {
                var val = data[name];
                if (!_checkField(name, val)) {
                    if (!_loadBox(name, val)) {
                        form.find('input[name="' + name + '"]').val(val);
                        form.find('textarea[name="' + name + '"]').val(val);
                        form.find('select[name="' + name + '"]').val(val);
                    }
                }
            }
        }

        function _checkField(name, val) {
            var cc = $(target).find('input[name="' + name + '"][type=radio], input[name="' + name + '"][type=checkbox]');
            if (cc.length) {
                //cc.prop('checked', false);
                cc.each(function() {
                    if (_isChecked($(this).val(), val)) {
                        $(this).prop('checked', true);
                    }
                });
                return true;
            }
            return false;
        }

        function _isChecked(v, val) {
            if (v == String(val) || $.inArray(v, $.isArray(val) ? val : [val]) >= 0) {
                return true;
            } else {
                return false;
            }
        }

        function _loadBox(name, val) {
            var field = $(target).find('input.combobox-value[name="' + name + '"]');
            if (field.length) {
				field.closest('.combobox').filter('.combobox-f').combobox('setValue', val); //兼容以前的
            	field.parent().find('.combobox-f').combobox('setValue', val);
                return true;
            }
            return false;
        }
    }

    /**
     * 清空表单
     */
    function clear(target) {
        $('input,select,textarea', target).each(function() {
            var t = this.type,
                tag = this.tagName.toLowerCase();
            if (t == 'text' || t == 'password' || tag == 'textarea')
                this.value = '';
            else if (t == 'checkbox' || t == 'radio')
                this.checked = false;
            else if (tag == 'select')
                this.selectedIndex = -1;

        });

        if ($.fn.combobox) {
            $('.combobox-f', target).combobox('clear');
        }
    }

    /**
     * 重置表单
     */
    function reset(target) {
        target.reset();
    }

    /**
     * 验证表单
     */
    function validate(target) {
        if ($.fn.validatebox) {
            var t = $(target);
            t.find('.validatebox-text:not(:disabled)').validatebox('validate');
            var invalidbox = t.find('.validatebox-invalid');
            invalidbox.filter(':not(:disabled):first').focus();
            return invalidbox.length == 0;
        }
        return true;
    }

    function setValidation(target, novalidate) {
        $(target).find('.validatebox-text:not(:disabled)').validatebox(novalidate ? 'disableValidation' : 'enableValidation');
    }

    function setEditable(target, editable) {
        if (editable) {
            $('input[type!="button"],textarea', target).removeAttr('readonly');
            $('select', target).removeAttr('disabled');
            $('.combobox-f', target).combobox('enable');
            //data-editable
            $('input[data-editable="false"],textarea[data-editable="false"]', target).attr('readonly', 'readonly');
            $('select[data-editable="false"]', target).attr('disabled', 'disabled');
            $('.combobox-f[data-editable="false"]', target).combobox('disable');
        } else {
            $('input[type!="button"],textarea', target).attr('readonly', 'readonly');
            $('select', target).attr('disabled', 'disabled');
            $('.combobox-f', target).combobox('disable');
        }
    }

    $.fn.form = function(options, param) {
        if (typeof options == 'string') {
            return $.fn.form.methods[options](this, param);
        }
    };

    $.fn.form.methods = {
        submit: function(jq, options) {
            return jq.each(function() {
                ajaxSubmit(this, $.extend({}, $.fn.form.defaults, options || {}));
            });
        },
        load: function(jq, data) {
            return jq.each(function() {
                load(this, data);
            });
        },
        clear: function(jq) {
            return jq.each(function() {
                clear(this);
            });
        },
        reset: function(jq) {
            return jq.each(function() {
                reset(this);
            });
        },
        validate: function(jq) {
            return validate(jq[0]);
        },
        disableValidation: function(jq) {
            return jq.each(function() {
                setValidation(this, true);
            });
        },
        enableValidation: function(jq) {
            return jq.each(function() {
                setValidation(this, false);
            });
        },
        disableEditable: function(jq) {
            return jq.each(function() {
                setEditable(this, false);
            });
        },
        enableEditable: function(jq) {
            return jq.each(function() {
                setEditable(this, true);
            });
        }
    };

    $.fn.form.defaults = {
        url: null,
        onSubmit: function() {},
        success: function(data) {}
    };
})(jQuery);
